package edu.cug.water.crawler.job.task.committee;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import edu.cug.water.crawler.common.annotation.BeanField;
import edu.cug.water.crawler.common.constant.Constant;
import edu.cug.water.crawler.common.constant.EsConstants;
import edu.cug.water.crawler.common.exception.RRException;
import edu.cug.water.crawler.common.utils.DateUtils;
import edu.cug.water.crawler.common.utils.EsUtils;
import edu.cug.water.crawler.job.entity.committee.HaiheRiver;
import edu.cug.water.crawler.job.request.RequestUtil;
import edu.cug.water.crawler.job.task.ITask;
import edu.cug.water.crawler.job.utils.AbstractCrawlerTask;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.lang.reflect.Field;
import java.util.*;

@Component("job:HaiheRiver")
@Slf4j
public class HaiheRiverTask extends AbstractCrawlerTask<HaiheRiver> implements ITask {

    @Autowired
    EsUtils esUtils;

    @Autowired
    RequestUtil requestUtil;

    @Override
    public int run(String params) throws IOException {

        init();

        ResponseEntity<String> response = getRequestBody();

        if (StringUtils.isEmpty(response.getBody()))
            throw new RRException(getClass().getName() + Constant.LogConstants.RESPONSE_IS_NULL.getValue());

        JSONObject jsonObject = (JSONObject) JSONObject.parse(response.getBody());
        int status = jsonObject.getIntValue("status");
        String msg = jsonObject.getString("message");
        log.info("HaiheRiver Request Data status: {}, {}", status, msg);

        JSONObject data = jsonObject.getJSONObject("data").getJSONObject("data");
        Set<String> keySet = new TreeSet<>(data.keySet());
        int i = 1, cnt = 0;
        for (String key : keySet) {
            JSONArray jsonArray = data.getJSONArray(key);
            List<Map<String, String>> list = parse(jsonArray, i ++, key);

            String s = esUtils.addDocuments(EsConstants.TypeConstant.HAIHE_RIVER_COMMITTEE.getValue() + "_" + key.toLowerCase(), list);
            Boolean aBoolean = esUtils.statusJudge(s);
            if (!aBoolean)
                throw new RRException(getClass().getName() + Constant.LogConstants.THE_PROCESS_OF_ES_STORE_FAILED.getValue());
            cnt += list.size();
        }
        return cnt;
    }

    @Override
    protected void init() {
        super.init();
        url = "http://www.hwcc.gov.cn/hwccapi/ysq/selectApi";
        headers.set("Host", "www.hwcc.gov.cn");
        headers.set("Connection", "keep-alive");
        headers.set("Accept", "application/json, text/plain, */*");
        headers.set("X-Requested-With", "XMLHttpRequest");
        headers.set("Referer", "http://www.hwcc.gov.cn/hwccapp/lyysq");
        headers.set("Accept-Encoding", "gzip, deflate");
        headers.set("Accept-Language", "en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7");
    }

    private List<Map<String, String>> parse(JSONArray data, int categoryIdx, String category) {
        List<Map<String, String>> results = new ArrayList<>();

        for (Object datum : data) {
            JSONObject temp = (JSONObject) datum;
            HaiheRiver entity = new HaiheRiver();
            Map<String, String> map = new HashMap<>();
            Field[] fields = entity.getClass().getDeclaredFields();

            for (Field field : fields) {
                BeanField annotation = field.getAnnotation(BeanField.class);

                if (annotation == null) continue;
                if (annotation.belongs() != 0) {
                    if (annotation.belongs() == -categoryIdx) continue;
                    if (annotation.belongs() != categoryIdx) continue;
                }

                map.put(field.getName(), (temp.get(annotation.property()) + "").trim());
            }
            map.put("createTime", DateUtils.formatDateTime(new Date()));
            results.add(map);
        }
        log.info("{} converts results：{}", getClass().getName() + "-" + category, results.size());
        return results;
    }

    @Override
    public ResponseEntity<String> getRequestBody() {
        return requestUtil.get(url, headers);
    }

    @Override
    public List<HaiheRiver> getDataFromStr(String requestBody) {
        return null;
    }
}
